/**
 * 对象公开的方法，在每个js引用时，可直接声明成$对象，这样可以写成$.extend
 */
const extend = function (target, obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10) {
   return extendBase(true, target, obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10);
}


/**
* 仿JQuery3.4.1版本写的$.extend方法，用来合并json对象
*/
function extendBase() {
   var options, name, src, copy, copyIsArray, clone,
       target = arguments[0] || {},
       i = 1,
       length = arguments.length,
       deep = false;

   if (typeof target === "boolean") {
       deep = target;
       target = arguments[i] || {};
       i++;
   }

   if (typeof target !== "object" && !isFunction(target)) {
       target = {};
   }

   if (i === length) {
       target = this;
       i--;
   }

   for (; i < length; i++) {

       if ((options = arguments[i]) != null) {

           for (name in options) {
               copy = options[name];

               if (name === "__proto__" || target === copy) {
                   continue;
               }

               if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
                   src = target[name];

                   if (copyIsArray && !Array.isArray(src)) {
                       clone = [];
                   } else if (!copyIsArray && !isPlainObject(src)) {
                       clone = {};
                   } else {
                       clone = src;
                   }

                   copyIsArray = false;

                   target[name] = extendBase(deep, clone, copy);

               } else if (copy !== undefined) {
                   target[name] = copy;
               }
           }
       }
   }

   return target;
}


function isFunction(obj) {
   return typeof obj === "function" && typeof obj.nodeType !== "number";
}


function isPlainObject(obj) {
   var proto, Ctor;

   var class2type = {};
   var toString = class2type.toString;
   var getProto = Object.getPrototypeOf;
   var hasOwn = class2type.hasOwnProperty;
   var fnToString = hasOwn.toString;
   var ObjectFunctionString = fnToString.call(Object);

   if (!obj || toString.call(obj) !== "[object Object]") {
       return false;
   }

   proto = getProto(obj);

   if (!proto) {
       return true;
   }

   Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
   return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}





module.exports = {
   extend: extend
}